#ifndef EXEC_H
#define EXEC_H

// void Exec_ADD (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     uint64_t rs1_val = (int64_t)xregs[rs1(inst)];
//     uint64_t rs2_val = (int64_t)xregs[rs2(inst)];
//     xregs[rd(inst)] = (uint64_t)((int64_t)xregs[rs1(inst)] + (int64_t)xregs[rs2(inst)]);

//     curCommitState.valid     = 1;
//     curCommitState.pc        = cpu_p->pc;
//     curCommitState.inst      = inst;
//     curCommitState.skip      = 0;
//     curCommitState.isRVC     = 0;
//     curCommitState.scFailed  = 0;
//     curCommitState.fused     = 0;
//     curCommitState.wen       = 1;
//     curCommitState.wdest     = rd(inst);
//     curCommitState.wdata     = xregs[rd(inst)];
//     brunch_valid             = 0;
//     brunch_addr              = 0;

// #ifdef DEBUG_INST
// printf("[pc: %08lx] ADD ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) + rs2<%s>[%02d](%016lx) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , rs1_val , riscv_abiX[rs2(inst)] , rs2(inst) , rs2_val  );
// #endif
// }

// void Exec_SUB (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     uint64_t rs1_val = (int64_t)xregs[rs1(inst)];
//     uint64_t rs2_val = (int64_t)xregs[rs2(inst)];
//     xregs[rd(inst)] = (uint64_t)((int64_t)xregs[rs1(inst)] - (int64_t)xregs[rs2(inst)]);
// #ifdef DEBUG_INST
// printf("[pc: %08lx] SUB ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) - rs2<%s>[%02d](%016lx) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , rs1_val , riscv_abiX[rs2(inst)] , rs2(inst) , rs2_val  );
// #endif
// }

// void Exec_SLT (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     uint64_t rs1_val = (int64_t)xregs[rs1(inst)];
//     uint64_t rs2_val = (int64_t)xregs[rs2(inst)];
//     xregs[rd(inst)] = ((int64_t)xregs[rs1(inst)] < (int64_t)xregs[rs2(inst)]) ? 1 : 0;
// #ifdef DEBUG_INST
// printf("[pc: %08lx] SLT ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) < rs2<%s>[%02d](%016lx) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , rs1_val , riscv_abiX[rs2(inst)] , rs2(inst) , rs2_val  );
// #endif
// }

// void Exec_SLTU (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     uint64_t rs1_val = (int64_t)xregs[rs1(inst)];
//     uint64_t rs2_val = (int64_t)xregs[rs2(inst)];
//     xregs[rd(inst)] = (xregs[rs1(inst)] < xregs[rs2(inst)]) ? 1 : 0;
// #ifdef DEBUG_INST
// printf("[pc: %08lx] SLTU ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) < rs2<%s>[%02d](%016lx) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , rs1_val , riscv_abiX[rs2(inst)] , rs2(inst) , rs2_val  );
// #endif
// }
// ///////////////////////////////
// void Exec_XOR (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = xregs[rs1(inst)] ^ xregs[rs2(inst)];
// #ifdef DEBUG_INST
// printf("[pc: %08lx] XOR ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) xor rs2<%s>[%02d](%016lx) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , riscv_abiX[rs2(inst)] , rs2(inst) , xregs[rs2(inst)]  );
// #endif
// }

// void Exec_OR (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = xregs[rs1(inst)] | xregs[rs2(inst)];
// #ifdef DEBUG_INST
// printf("[pc: %08lx] OR ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) or rs2<%s>[%02d](%016lx) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , riscv_abiX[rs2(inst)] , rs2(inst) , xregs[rs2(inst)]  );
// #endif
// }

// void Exec_AND (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = xregs[rs1(inst)] & xregs[rs2(inst)];
// #ifdef DEBUG_INST
// printf("[pc: %08lx] AND ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) and rs2<%s>[%02d](%016lx) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , riscv_abiX[rs2(inst)] , rs2(inst) , xregs[rs2(inst)]  );
// #endif
// }

// void Exec_SLL (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = xregs[rs1(inst)] << (xregs[rs2(inst)] & 0x1f);
// #ifdef DEBUG_INST
// printf("[pc: %08lx] SLL ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) << rs2<%s>[%02d](%016lx) shamt(%02ld) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , riscv_abiX[rs2(inst)] , rs2(inst) , xregs[rs2(inst)] , (xregs[rs2(inst)] & 0x1f) );
// #endif
// }
// //////////////////////////////////////////////////////////////////////////////////////////////

// void Exec_ADDW (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = (int64_t)((xregs[rs1(inst)] + xregs[rs2(inst)]) & 0xffffffff);
// #ifdef DEBUG_INST
// printf("[pc: %08lx] ADDW ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) + rs2<%s>[%02d](%016lx) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , riscv_abiX[rs2(inst)] , rs2(inst) , xregs[rs2(inst)] );
// #endif
// }

// void Exec_SUBW (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = (int64_t)((xregs[rs1(inst)] - xregs[rs2(inst)]) & 0xffffffff);
// #ifdef DEBUG_INST
// printf("[pc: %08lx] SUBW ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) - rs2<%s>[%02d](%016lx) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , riscv_abiX[rs2(inst)] , rs2(inst) , xregs[rs2(inst)] );
// #endif
// }

// void Exec_SLLW (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = (int64_t)(uint32_t)(xregs[rs1(inst)] << (xregs[rs2(inst)] & 0x1f));
// #ifdef DEBUG_INST
// printf("[pc: %08lx] SLLW ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) << rs2<%s>[%02d](%016lx) shamt(%02ld) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , riscv_abiX[rs2(inst)] , rs2(inst) , xregs[rs2(inst)] , (xregs[rs2(inst)] & 0x1f) );
// #endif
// }

// void Exec_SRLW (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = (int64_t)(uint32_t)((uint32_t)xregs[rs1(inst)] >> (xregs[rs2(inst)] & 0x1f));
// #ifdef DEBUG_INST
// printf("[pc: %08lx] SRLW ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) >> rs2<%s>[%02d](%016lx) shamt(%02ld) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , riscv_abiX[rs2(inst)] , rs2(inst) , xregs[rs2(inst)] , (xregs[rs2(inst)] & 0x1f) );
// #endif
// }

// void Exec_SRAW (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = (uint64_t)(int32_t)(xregs[rs1(inst)] >> (xregs[rs2(inst)] & 0x1f));
// #ifdef DEBUG_INST
// printf("[pc: %08lx] SRL ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) >> rs2<%s>[%02d](%016lx) shamt(%02ld) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , riscv_abiX[rs2(inst)] , rs2(inst) , xregs[rs2(inst)] , (xregs[rs2(inst)] & 0x1f) );
// #endif
// }

// void Exec_SRL (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = xregs[rs1(inst)] >> (xregs[rs2(inst)] & 0x1f);
// #ifdef DEBUG_INST
// printf("[pc: %08lx] SRL ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) >> rs2<%s>[%02d](%016lx) shamt(%02ld) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , riscv_abiX[rs2(inst)] , rs2(inst) , xregs[rs2(inst)] , (xregs[rs2(inst)] & 0x1f) );
// #endif
// }

// void Exec_SRA (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = (uint64_t)((uint64_t)(xregs[rs1(inst)]) >> (xregs[rs2(inst)] & 0x1f));
// #ifdef DEBUG_INST
// printf("[pc: %08lx] SRA ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) >> rs2<%s>[%02d](%016lx) shamt(%02ld) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , riscv_abiX[rs2(inst)] , rs2(inst) , xregs[rs2(inst)] , (xregs[rs2(inst)] & 0x1f) );
// #endif
// }

void Exec_ADDI (cpu * p, uint32_t inst){

    p->curCommitState.valid     = 1;
    p->curCommitState.pc        = p->curContext.pc;
    p->curCommitState.inst      = inst;
    p->curCommitState.skip      = 0;
    p->curCommitState.isRVC     = 0;
    p->curCommitState.scFailed  = 0;
    p->curCommitState.fused     = 0;
    p->curCommitState.wen       = 1;
    p->curCommitState.wdest     = rd(inst);
    p->curCommitState.wdata     = p->curContext.xregs[rs1(inst)] + Imm_I(inst);
    p->brunch_valid             = 0;
    p->brunch_addr              = 0;

// #ifdef DEBUG_INST
// printf("[pc: %08lx] ADDI ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) + Imm_I(%016lx) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , Imm_I(inst) );
// #endif
}

// void Exec_ADDIW (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = (int64_t)(uint32_t)(xregs[rs1(inst)] + Imm_I(inst));
// #ifdef DEBUG_INST
// printf("[pc: %08lx] ADDIW ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) + Imm_I(%016lx) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , Imm_I(inst) );
// #endif
// }

// void Exec_SLTI (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = ((int64_t)xregs[rs1(inst)] < (int64_t)Imm_I(inst)) ? 1 : 0;

// #ifdef DEBUG_INST
// printf("[pc: %08lx] SLTI ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) < Imm_I(%016lx) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , Imm_I(inst) );
// #endif
// }

// void Exec_SLTIU (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = (xregs[rs1(inst)] < (int64_t)Imm_I(inst)) ? 1 : 0;

// #ifdef DEBUG_INST
// printf("[pc: %08lx] SLTIU ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) < Imm_I(%016lx) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , Imm_I(inst) );
// #endif
// }

// void Exec_XORI (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = (xregs[rs1(inst)] ^ (int64_t)Imm_I(inst));

// #ifdef DEBUG_INST
// printf("[pc: %08lx] XORI ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) xor Imm_I(%016lx) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , Imm_I(inst) );
// #endif
// }

// void Exec_ORI (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = (xregs[rs1(inst)] | (int64_t)Imm_I(inst));

// #ifdef DEBUG_INST
// printf("[pc: %08lx] ORI ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) or Imm_I(%016lx) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , Imm_I(inst) );
// #endif
// }

// void Exec_ANDI (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = (xregs[rs1(inst)] & (int64_t)Imm_I(inst));

// #ifdef DEBUG_INST
// printf("[pc: %08lx] ANDI ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) and Imm_I(%016lx) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , Imm_I(inst) );
// #endif
// }


// void Exec_SLLI (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = xregs[rs1(inst)] << (Imm_I(inst) & 0x3f);
// #ifdef DEBUG_INST
// printf("[pc: %08lx] SLLI ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) << Imm_I(%016ld) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , Imm_I(inst) );
// #endif
// }

// void Exec_SLLIW (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = (int64_t)(uint32_t)(xregs[rs1(inst)] << (Imm_I(inst) & 0x3f));
// #ifdef DEBUG_INST
// printf("[pc: %08lx] SLLIW ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) << Imm_I(%016ld) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , Imm_I(inst) );
// #endif
// }

// void Exec_SRLI (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = xregs[rs1(inst)] >> (Imm_I(inst) & 0x3f);
// #ifdef DEBUG_INST
// printf("[pc: %08lx] SRLI ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) >> Imm_I(%016ld) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , Imm_I(inst) );
// #endif
// }

// void Exec_SRLIW (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = (int64_t)(uint32_t)(xregs[rs1(inst)] >> (Imm_I(inst) & 0x3f));
// #ifdef DEBUG_INST
// printf("[pc: %08lx] SRLIW ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) >> Imm_I(%016ld) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , Imm_I(inst) );
// #endif
// }

// void Exec_SRAI (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = (uint64_t)((uint64_t)(xregs[rs1(inst)]) >> (Imm_I(inst) & 0x3f));
// #ifdef DEBUG_INST
// printf("[pc: %08lx] SRLI ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) >> Imm_I(%016ld) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , Imm_I(inst) );
// #endif
// }

// void Exec_SRAIW (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = ((uint64_t)((uint32_t)xregs[rs1(inst)]) >> (Imm_I(inst) & 0x3f));
// #ifdef DEBUG_INST
// printf("[pc: %08lx] SRLI ->> rd<%s>[%02d](%016lx) = rs1<%s>[%02d](%016lx) >> Imm_I(%016ld) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , Imm_I(inst) );
// #endif
// }

// void Exec_AUIPC (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = (uint64_t)((int64_t)cpu_p->pc + (int64_t)Imm_U(inst));
// #ifdef DEBUG_INST
// printf("[pc: %08lx] AUIPC ->> rd<%s>[%02d](%016lx) = pc(%08lx) + Imm_U(%016lx) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , cpu_p->pc , Imm_U(inst));
// #endif
// }

// void Exec_LUI (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     cpu_p->xregs[rd(inst)] = (uint64_t)(int64_t)(inst & 0xfffff000);

// #ifdef DEBUG_INST
// printf("[pc: %08lx] LUI ->> rd<%s>[%02d](%016lx) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)]);
// #endif
// }

// void Exec_JAL (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     xregs[rd(inst)] = cpu_p->pc + 4;
//     cpu_p->pc += (int64_t)Imm_J(inst);
// #ifdef DEBUG_INST
// printf("[pc: %08lx] JAL ->> rd<%s>[%02d](%016lx) = pc(%08lx) + Imm_J(%016lx) \n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , cpu_p->pc , Imm_J(inst));
// #endif
// }

// void Exec_JALR (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     uint64_t pc = cpu_p->pc;
//     xregs[rd(inst)] = cpu_p->pc + 4;
//     cpu_p->pc = (cpu_p->xregs[rs1(inst)] + (int64_t) Imm_I(inst)) & 0xfffffffe;
// #ifdef DEBUG_INST
// printf("[pc: %08lx] JALR ->> rd<%s>[%02d](%016lx) = pc + 4 / Target(%08lx) = rs1<%s>[%02d](%016lx) + Imm_I(%016ld) \n",
//          pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , cpu_p->pc ,riscv_abiX[rs1(inst)] , rs1(inst) , xregs[rs1(inst)] , Imm_I(inst) );
// #endif
// }

// void Exec_BEQ (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     if(cpu_p->xregs[rs1(inst)] == cpu_p->xregs[rs2(inst)]){
//        uint64_t pc = cpu_p->pc + Imm_B(inst);
// #ifdef DEBUG_INST
// printf("[pc: %08lx] BEQ ->>  Jump to Target [%08lx] \n", cpu_p->pc , pc);
// #endif
//         cpu_p->pc = pc;
//     }else {
//         cpu_p->pc += 4;
// #ifdef DEBUG_INST
// printf("[pc: %08lx] BEQ ->>  Not Jump \n", cpu_p->pc );
// #endif
//     }
// }

// void Exec_BNE (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     if(cpu_p->xregs[rs1(inst)] != cpu_p->xregs[rs2(inst)]){
//        uint64_t pc = cpu_p->pc + Imm_B(inst);
// #ifdef DEBUG_INST
// printf("[pc: %08lx] BNE ->>  Jump to Target [%08lx] \n", cpu_p->pc , pc);
// #endif
//         cpu_p->pc = pc;
//     }else {
//         cpu_p->pc += 4;
// #ifdef DEBUG_INST
// printf("[pc: %08lx] BNE ->>  Not Jump \n", cpu_p->pc );
// #endif
//     }
// }
// void Exec_BLT (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     if((int64_t)cpu_p->xregs[rs1(inst)] < (int64_t)cpu_p->xregs[rs2(inst)]){
//        uint64_t pc = cpu_p->pc + Imm_B(inst);
// #ifdef DEBUG_INST
// printf("[pc: %08lx] BLT ->>  Jump to Target [%08lx] \n", cpu_p->pc , pc);
// #endif
//         cpu_p->pc = pc;
//     }else {
//         cpu_p->pc += 4;
// #ifdef DEBUG_INST
// printf("[pc: %08lx] BLT ->>  Not Jump \n", cpu_p->pc );
// #endif
//     }
// }
// void Exec_BGE (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     if((int64_t)cpu_p->xregs[rs1(inst)] >= (int64_t)cpu_p->xregs[rs2(inst)]){
//        uint64_t pc = cpu_p->pc + Imm_B(inst);
// #ifdef DEBUG_INST
// printf("[pc: %08lx] BGE ->>  Jump to Target [%08lx] \n", cpu_p->pc , pc);
// #endif
//         cpu_p->pc = pc;
//     }else {
//         cpu_p->pc += 4;
// #ifdef DEBUG_INST
// printf("[pc: %08lx] BGE ->>  Not Jump \n", cpu_p->pc );
// #endif
//     }
// }

// void Exec_BLTU (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     if(cpu_p->xregs[rs1(inst)] < cpu_p->xregs[rs2(inst)]){
//        uint64_t pc = cpu_p->pc + Imm_B(inst);
// #ifdef DEBUG_INST
// printf("[pc: %08lx] BLTU ->>  Jump to Target [%08lx] \n", cpu_p->pc , pc);
// #endif
//         cpu_p->pc = pc;
//     }else {
//         cpu_p->pc += 4;
// #ifdef DEBUG_INST
// printf("[pc: %08lx] BLTU ->>  Not Jump \n", cpu_p->pc );
// #endif
//     }
// }

// void Exec_BGEU (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     if(cpu_p->xregs[rs1(inst)] >= cpu_p->xregs[rs2(inst)]){
//        uint64_t pc = cpu_p->pc + Imm_B(inst);
// #ifdef DEBUG_INST
// printf("[pc: %08lx] BGEU ->>  Jump to Target [%08lx] \n", cpu_p->pc , pc);
// #endif
//         cpu_p->pc = pc;
//     }else {
//         cpu_p->pc += 4;
// #ifdef DEBUG_INST
// printf("[pc: %08lx] BGEU ->>  Not Jump \n", cpu_p->pc );
// #endif
//     }
// }

// void Exec_LB (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     uint64_t addr = xregs[rs1(inst)] + (int64_t) Imm_I(inst);
//     uint64_t data;
//     cpu_p->bus_p->read(addr,&data,1);
//     xregs[rd(inst)] = (int64_t)((int8_t)(data & 0xff));

// #ifdef DEBUG_INST
// printf("[pc: %08lx] LB ->> rd<%s>[%02d](%016lx) = Mem[%08lx]\n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , addr);
// #endif
// }

// void Exec_LH (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     uint64_t addr = xregs[rs1(inst)] + (int64_t) Imm_I(inst);
//     uint64_t data;
//     cpu_p->bus_p->read(addr,&data,2);
//     xregs[rd(inst)] = (int64_t)((int16_t)(data & 0xffff));

// #ifdef DEBUG_INST
// printf("[pc: %08lx] LH ->> rd<%s>[%02d](%016lx) = Mem[%08lx]\n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , addr);
// #endif
// }

// void Exec_LW (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     uint64_t addr = xregs[rs1(inst)] + (int64_t) Imm_I(inst);
//     uint64_t data;
//     cpu_p->bus_p->read(addr,&data,4);
//     xregs[rd(inst)] = (int64_t)((int32_t)(data & 0xffffffff));

// #ifdef DEBUG_INST
// printf("[pc: %08lx] LW ->> rd<%s>[%02d](%016lx) = Mem[%08lx]\n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , addr);
// #endif
// }

// void Exec_LD (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     uint64_t addr = xregs[rs1(inst)] + (int64_t) Imm_I(inst);
//     uint64_t data;
//     cpu_p->bus_p->read(addr,&data,8);
//     xregs[rd(inst)] = data;

// #ifdef DEBUG_INST
// printf("[pc: %08lx] LD ->> rd<%s>[%02d](%016lx) = Mem[%08lx]\n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , addr);
// #endif
// }

// void Exec_LBU (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     uint64_t addr = xregs[rs1(inst)] + (int64_t) Imm_I(inst);
//     uint64_t data;
//     cpu_p->bus_p->read(addr,&data,1);
//     xregs[rd(inst)] = (data & 0xff);

// #ifdef DEBUG_INST
// printf("[pc: %08lx] LB ->> rd<%s>[%02d](%016lx) = Mem[%08lx]\n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , addr);
// #endif
// }

// void Exec_LHU (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     uint64_t addr = xregs[rs1(inst)] + (int64_t) Imm_I(inst);
//     uint64_t data;
//     cpu_p->bus_p->read(addr,&data,2);
//     xregs[rd(inst)] = (data & 0xffff);

// #ifdef DEBUG_INST
// printf("[pc: %08lx] LH ->> rd<%s>[%02d](%016lx) = Mem[%08lx]\n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , addr);
// #endif
// }

// void Exec_LWU (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     uint64_t addr = xregs[rs1(inst)] + (int64_t) Imm_I(inst);
//     uint64_t data;
//     cpu_p->bus_p->read(addr,&data,4);
//     xregs[rd(inst)] = (data & 0xffffffff);

// #ifdef DEBUG_INST
// printf("[pc: %08lx] LW ->> rd<%s>[%02d](%016lx) = Mem[%08lx]\n",
//          cpu_p->pc , riscv_abiX[rd(inst)] ,rd(inst) , xregs[rd(inst)] , addr);
// #endif
// }

// void Exec_SB (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     uint64_t addr = xregs[rs1(inst)] + (int64_t) Imm_S(inst);
//     uint64_t data = xregs[rs2(inst)];
//     cpu_p->bus_p->write(addr, data , 1);

// #ifdef DEBUG_INST
// printf("[pc: %08lx] SB ->> Mem[%08lx] = rs2<%s>[%02d](%016lx)\n",
//          cpu_p->pc , addr , riscv_abiX[rs2(inst)] ,rs2(inst) , xregs[rs2(inst)] );
// #endif
// }

// void Exec_SH (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     uint64_t addr = xregs[rs1(inst)] + (int64_t) Imm_S(inst);
//     uint64_t data = xregs[rs2(inst)];
//     cpu_p->bus_p->write(addr, data , 2);

// #ifdef DEBUG_INST
// printf("[pc: %08lx] SH ->> Mem[%08lx] = rs2<%s>[%02d](%016lx)\n",
//          cpu_p->pc , addr , riscv_abiX[rs2(inst)] ,rs2(inst) , xregs[rs2(inst)] );
// #endif
// }

// void Exec_SW (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     uint64_t addr = xregs[rs1(inst)] + (int64_t) Imm_S(inst);
//     uint64_t data = xregs[rs2(inst)];
//     cpu_p->bus_p->write(addr, data , 4);

// #ifdef DEBUG_INST
// printf("[pc: %08lx] SW ->> Mem[%08lx] = rs2<%s>[%02d](%016lx)\n",
//          cpu_p->pc , addr , riscv_abiX[rs2(inst)] ,rs2(inst) , xregs[rs2(inst)] );
// #endif
// }

// void Exec_SD (cpu * cpu_p , uint32_t inst){
//     uint64_t * xregs = cpu_p->xregs;
//     uint64_t addr = xregs[rs1(inst)] + (int64_t) Imm_S(inst);
//     uint64_t data = xregs[rs2(inst)];
//     cpu_p->bus_p->write(addr, data , 8);

// #ifdef DEBUG_INST
// printf("[pc: %08lx] SD ->> Mem[%08lx] = rs2<%s>[%02d](%016lx)\n",
//          cpu_p->pc , addr , riscv_abiX[rs2(inst)] ,rs2(inst) , xregs[rs2(inst)] );
// #endif
// }

#endif